/********************************************************************************
* @File name: breathled.c
* @Author: Loganx
* @Blog: https://www.cnblogs.com/loganxiang
* @Version: 1.0(2025-10-09)
* @Description: STC32G单片机七彩LED驱动，可以实现单色点亮、单色呼吸、七彩转换
********************************************************************************
* 本软件使用了STC的STC32G官方库；
********************************************************************************/
#include "Lib/Config.h"
#include "Lib/STC32G_GPIO.h"
#include "Lib/STC32G_PWM.h"
#include "Lib/STC32G_NVIC.h"
#include "Lib/STC32G_Switch.h"
#include "breathled.h"

unsigned char BLEDBreathMode;
unsigned char BLEDColor;
unsigned int BLEDScanCycle;

unsigned int code ColorRaw[9][3] = {
	{0x0000,0x0000,0x0000},					//OFF
	{BLED_BRIGHT,0x0000,0x0000},			//RED
	{BLED_BRIGHT,BLED_BRIGHT >> 2,0x0000},	//ORANGE
	{BLED_BRIGHT,BLED_BRIGHT,0x0000},		//YELLOW
	{0x0000,BLED_BRIGHT,0x0000},			//GREEN
	{0x0000,BLED_BRIGHT,BLED_BRIGHT},		//CYAN
	{0x0000,0x0000,BLED_BRIGHT},			//BLUE
	{BLED_BRIGHT,0x0000,BLED_BRIGHT},		//PURPLE
	{BLED_BRIGHT,BLED_BRIGHT,BLED_BRIGHT}};	//WHITE

void BLEDInit(void){
	GPIO_InitTypeDef gpio;
	PWMx_InitDefine pwm;
	
	gpio.Mode = GPIO_OUT_PP;
	gpio.Pin = GPIO_Pin_LOW;
	
	GPIO_Inilize(GPIO_P2,&gpio);

	pwm.PWM_Mode = CCMRn_PWM_MODE1;
	pwm.PWM_Duty = 0x0000;
	pwm.PWM_EnoSelect = ENO5P;
	PWM_Configuration(PWM5, &pwm);
	
	pwm.PWM_EnoSelect = ENO6P;
	PWM_Configuration(PWM6, &pwm);
	
	pwm.PWM_EnoSelect = ENO7P;
	PWM_Configuration(PWM7, &pwm);
	
	pwm.PWM_Period = 0x1000; 
	pwm.PWM_DeadTime = 0;
	pwm.PWM_MainOutEnable= ENABLE;
	pwm.PWM_CEN_Enable   = ENABLE; 
	PWM_Configuration(PWMB, &pwm);
	
	PWM5_SW(PWM5_SW_P20);
	PWM6_SW(PWM6_SW_P21);
	PWM7_SW(PWM7_SW_P22);
	
	NVIC_PWM_Init(PWMB,DISABLE,Priority_0);
}

void BLEDTurnOn(unsigned char color){
	unsigned int *pDuty;
	
	BLEDColor = color;
	BLEDBreathMode = BLED_MODE_OFF;
	pDuty = ColorRaw[color];

	PWMB_Duty5(pDuty[0]);
	PWMB_Duty6(pDuty[1]);
	PWMB_Duty7(pDuty[2]);
}

void BLEDDisplayColor(unsigned char red,unsigned char green,unsigned char blue){
	PWMB_Duty5((unsigned int)red << 4);
	PWMB_Duty6((unsigned int)green << 4);
	PWMB_Duty7((unsigned int)blue << 4);
}

void BLEDTurnOff(void){
	BLEDColor = BLED_COLOR_OFF;
	BLEDBreathMode = BLED_MODE_OFF;
	
	PWMB_Duty5(0x0000);
	PWMB_Duty6(0x0000);
	PWMB_Duty7(0x0000);
}

void BLEDBreath(uint8 mode,uint8 color){
	BLEDColor = color;
	BLEDBreathMode = mode;
	BLEDScanCycle = 0;
}

//Systick callback(20ms)
void SystickCallbackBLED(void){
	unsigned int *pDuty;
	
	if(BLEDBreathMode == BLED_MODE_SINGLE){
		pDuty = ColorRaw[BLEDColor];
		
		if(++BLEDScanCycle > 128)
			BLEDScanCycle = 0;
		if(BLEDScanCycle < 64){
			PWMB_Duty5(pDuty[0] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle);
			PWMB_Duty6(pDuty[1] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle);
			PWMB_Duty7(pDuty[2] - ((BLED_BRIGHT - 0x0100) >> 6) * BLEDScanCycle);
		}
		else{
			PWMB_Duty5(pDuty[0] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle));
			PWMB_Duty6(pDuty[1] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle));
			PWMB_Duty7(pDuty[2] - ((BLED_BRIGHT - 0x0100) >> 6) * (128 - BLEDScanCycle));
		}
	}
	else if(BLEDBreathMode == BLED_MODE_COLOR){
		if(++BLEDScanCycle > 448)
			BLEDScanCycle = 0;
		if(BLEDScanCycle < 64){
			PWMB_Duty5(BLED_BRIGHT);
			PWMB_Duty6((BLED_BRIGHT >> 6) * BLEDScanCycle);
			PWMB_Duty7(0x0000);
		}
		else if(BLEDScanCycle < 128){
			PWMB_Duty5(BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-64));
			PWMB_Duty6(BLED_BRIGHT);
			PWMB_Duty7(0x0000);
		}
		else if(BLEDScanCycle < 192){
			PWMB_Duty5(0x0000);
			PWMB_Duty6(BLED_BRIGHT);
			PWMB_Duty7((BLED_BRIGHT >> 6) * (BLEDScanCycle-128));
		}
		else if(BLEDScanCycle < 256){
			PWMB_Duty5(0x0000);
			PWMB_Duty6(BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-192));
			PWMB_Duty7(BLED_BRIGHT);
		}
		else if(BLEDScanCycle < 320){
			PWMB_Duty5((BLED_BRIGHT >> 6) * (BLEDScanCycle-256));
			PWMB_Duty6(0x0000);
			PWMB_Duty7(BLED_BRIGHT);
		}
		else if(BLEDScanCycle < 384){
			PWMB_Duty5(BLED_BRIGHT);
			PWMB_Duty6(0x0000);
			PWMB_Duty7(BLED_BRIGHT - (BLED_BRIGHT >> 6) * (BLEDScanCycle-320));
		}
	}
	else
		BLEDScanCycle = 0;
}